Embodiments described herein relate to FPGA-based coherent accelerators, and more specifically, to techniques for enabling the use of poll and select subroutines with FPGA-based coherent accelerator block and character devices.
Conventional hardware accelerators (e.g., PCI-based accelerators) perform operations requiring direct memory access (DMA) via a stack that includes a number of layers, providing user applications with access to the hardware accelerator. The hardware accelerator directs the data to a physical memory address from a storage device attached to the hardware accelerator. The operating system sets up DMA to corresponding pages of physical memory for the application (i.e., a buffer for the application). Doing so allows the hardware accelerator to arbitrate on a connected bus (e.g., a PCI bus) to transfer I/O operations and system calls to the storage device via a series of SCSI commands executed in the hardware accelerator.
Some FPGA-based hardware accelerators provide an application with direct access to the hardware accelerator. For example, an FPGA-based coherent accelerator allows an application to execute SCSI commands directly within application memory. In contrast to conventional hardware accelerators that need physical addresses to execute bus commands, coherent accelerators use effective addresses to issue bus commands to an attached storage device. As a result, an operating system does not need to perform actions that are typical (and computationally expensive) to a conventional hardware accelerator, such as translating effective addresses to physical addresses, which requires steps such as pinning memory pages to prevent page faults. A coherent accelerator translates effective addresses to real addresses while accelerating a function. Therefore, the operating system, via the coherent accelerator, allows page faults to occur, handling the page faults such that the accelerator may continue to access application memory. This approach greatly reduces the length of instructions required to set up a DMA path for data transfer.
In some cases, applications that perform operations via FPGA-based coherent accelerators may be interested in knowing when certain events (or exceptions) occur on the coherent accelerators. Examples of these events can include pending page faults, errors, I/O completion events, and other interrupts. Generally, an application can use system calls, e.g., such as poll( ) select( ) devpoll( ) pollset( ) etc., to check for exceptions from an I/O device. For example, these system calls generally watch sets of file descriptors for events, such as incoming data ready to receive, sockets ready to send data to, errors, etc. When an event occurs on one of a set of file descriptors, the system call returns to the application, alerting the application as to which file descriptor experienced the particular event.
The use of system calls to check for exceptions generally works well with devices with a channel (e.g., such as multiplexed devices like streams) but not for devices without a channel (e.g., such as block devices, etc.). A character device, in general, refers to a device that communicates data character by character. Examples of character devices can include serial ports, parallel ports, sound cards, etc. A block device, in general, refers to a device that is accessed through buffer cache and communicates data in blocks. Examples of block devices include disk drives, USB memory keys, etc. In some cases, FPGA-based coherent accelerators may operate as block devices, character devices or multiplexed devices. Therefore, it may be desirable to allow FPGA-based coherent accelerators (e.g., which may be block devices, character devices, multiplexed devices, etc.) to also poll on exceptions via system calls, such as poll( ) select( ) etc.